package com.tmall.testgen.client.runinspring;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class AutoConfigReplacer {

	private static String autoConfigPath="/META-INF/autoconf/auto-config.xml";
	/**
	 * 
	 * @param rootAndautoConfigPath
	 */
	public static void handleAutoConfig(List<String> projectClassPathRoot){
		if(projectClassPathRoot==null)
			return;
		
		for(String path:projectClassPathRoot){
			try {
				replaceFile(path,path+autoConfigPath);
			} catch (Exception e) {
			}
		}
	}
	
	public static void repaceFileUnderWebApp(String appPath){
	    
//	    try {
//	        replaceFile(appPath,appPath+autoConfigPath);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
	}
	
	
	private static  void replaceFile(String classRootPath,String path) throws Exception{
		Config config=getAutoConfig(path);
		
		
		VelocityEngine velocityEngine = new VelocityEngine();
		velocityEngine.setProperty("input.encoding", "UTF-8");
		
	   // velocityEngine.setProperty(Velocity.RESOURCE_LOADER, "class");
	    velocityEngine.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
//	    velocityEngine.setProperty("class.resource.loader.class","org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); 
	    Thread.currentThread().setContextClassLoader(AutoConfigReplacer.class.getClassLoader());
	    velocityEngine.init();
	    
	    VelocityContext velocityContext = new VelocityContext();
	    
	    Map<String,String> needReplace=new HashMap<String,String>();
		for(Property p:config.getGroup()){
			String key=p.getName().replaceAll("\\.", "\\\\.");
			String value=p.getName().replaceAll("\\.", "_");
			
			needReplace.put(key, value);
			velocityContext.put(value, p.getDefaultValue());
		}
		
		
	    
		for(Generate g:config.getScript()){
			String des=g.getDestfile()==null?g.getTemplate():g.getDestfile();
			
			replaceFile(classRootPath+"/"+des,needReplace);
			
		     Template template = velocityEngine.getTemplate(classRootPath+"/"+des);
		     if(g.getCharset()!=null)
		    	 velocityEngine.setProperty("output.encoding", g.getCharset());
		     
		     StringWriter stringWriter = new StringWriter();
		     template.merge(velocityContext, stringWriter);
		     write2File(new File(classRootPath+"/"+des),stringWriter.toString().trim());
		}
		
			    
	}
	
	private static  Config getAutoConfig(String path) throws Exception{
		XStream xstream = new XStream(new DomDriver  ());
		xstream.alias("config", Config.class);
		xstream.alias("property", Property.class);
		xstream.useAttributeFor(Property.class, "name");
		xstream.useAttributeFor(Property.class, "defaultValue");
		xstream.alias("generate", Generate.class);
		xstream.useAttributeFor(Generate.class, "template");
		xstream.useAttributeFor(Generate.class, "destfile");
		xstream.useAttributeFor(Generate.class, "charset");
		return (Config) xstream.fromXML(new File(path));  
		//return (Config) xstream.fromXML(new File("D:\\aliwork\\workspace\\testgen\\src\\com\\tmall\\testgen\\client\\genfile\\autoconfighandle\\auto-config.xml"));  
	}
	private static  void replaceFile(String path,Map<String,String> needReplaces) throws Exception{
		
		String content;
		File file = new File(path);
		InputStreamReader isr=new InputStreamReader(new FileInputStream(file),"UTF-8");
        char[] temp=new char[(int) file.length()];
        isr.read(temp);
        isr.close();
        
        content=new String(temp);
        
        for(String needReplace:needReplaces.keySet() ){
        	content= content.replaceAll(needReplace,needReplaces.get(needReplace));
        }
            
        write2File(file,content);

	}
	
	private static  void write2File(File file,String content) throws Exception{
		 OutputStreamWriter out=new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
        out.write(content);
        out.flush();
        out.close();
	}
	
	
	class Config {
		private List<Property> group;
		private List<Generate> script;
		public List<Property> getGroup() {
			return group;
		}
		public void setGroup(List<Property> group) {
			this.group = group;
		}
		public List<Generate> getScript() {
			return script;
		}
		public void setScript(List<Generate> script) {
			this.script = script;
		}
	}

	class Generate {
		private String template;
		private String destfile;
		private String charset;
		public String getTemplate() {
			return template;
		}
		public void setTemplate(String template) {
			this.template = template;
		}
		public String getDestfile() {
			return destfile;
		}
		public void setDestfile(String destfile) {
			this.destfile = destfile;
		}
		public String getCharset() {
			return charset;
		}
		public void setCharset(String charset) {
			this.charset = charset;
		}
		
	}


	class Property {
		private String name;
		private String defaultValue;
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public String getDefaultValue() {
			return defaultValue;
		}
		public void setDefaultValue(String defaultValue) {
			this.defaultValue = defaultValue;
		}
	}

}
